﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using EfficientlyLazy.PhotoFramer.Entity;
using EfficientlyLazy.PhotoFramer.Repository;

namespace EfficientlyLazy.PhotoFramer.Service
{
    [ServiceFactory]
    internal class SettingService : ISettingService
    {
        private readonly IRepository<GlobalSetting> _globalSettingRepository;

        public SettingService(IRepository<GlobalSetting> globalSettingRepository)
        {
            _globalSettingRepository = globalSettingRepository;
        }

        public virtual T Get<T>(GlobalSettingName<T> settingName)
        {
            var setting = _globalSettingRepository.All()
                .Where(x => x.Name == settingName.Name)
                .FirstOrDefault();

            if (setting != null)
            {
                return (T)Convert.ChangeType(setting.Value, typeof(T));
            }

            return settingName.Default;
        }

        public virtual T Get<T>(GlobalSettingName<T> settingName, T defaultValue)
        {
            var setting = _globalSettingRepository.All()
                .Where(x => x.Name == settingName.Name)
                .FirstOrDefault();

            if (setting != null)
            {
                return (T)Convert.ChangeType(setting.Value, typeof (T));
            }

            return defaultValue;
        }

        public virtual void Set<T>(GlobalSettingName<T> settingName, T value)
        {
            var setting = _globalSettingRepository.All()
                              .Where(x => x.Name == settingName.Name)
                              .FirstOrDefault() ?? new GlobalSetting
                                                       {
                                                           Name = settingName.Name
                                                       };

            setting.Value = value.ToString();

            _globalSettingRepository.SaveAndFlush(setting);
        }

        public virtual SystemSettings LoadSystemSettings()
        {
            var settings = new List<GlobalSetting>();

            foreach (var fieldInfo in typeof(GlobalSettings).GetFields(BindingFlags.Public | BindingFlags.Static))
            {
                var fieldValue = fieldInfo.GetValue(null);

                var name = fieldValue.GetType().GetProperty("Name").GetValue(fieldValue, null).ToString();

                var setting = _globalSettingRepository.All().Where(x => x.Name == name).FirstOrDefault();

                if (setting == null)
                {
                    continue;
                }

                settings.Add(setting);
            }

            return new SystemSettings(settings);
        }

        public virtual void SaveSystemSettings(SystemSettings systemSettings)
        {
            foreach (var change in systemSettings.GetChanges())
            {
                var setting = _globalSettingRepository.All()
                                  .Where(x => x.Name == change.Name)
                                  .FirstOrDefault() ?? new GlobalSetting
                                                           {
                                                               Name = change.Name
                                                           };

                setting.Value = change.NewValue;

                _globalSettingRepository.SaveAndFlush(setting);
            }
        }
    }
}
